#include <stdio.h>
#include <stdlib.h>

#ifndef M8C_C_HEADER
#define FALSE 0
#define TRUE  1
#endif

#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x0f
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80


#define TASK_IS_QUEUED			BIT0
#define TASK_TIMER_IS_ACTIVE	BIT1


#define MILISECONDS_INCREMENT 	33
#define SECONDS_INCREMENT		32768

/*
 * Macros for setting flags in main program control loop
 */
#define sched_setScheduleFlag(flag) 		sched_controlFlags |= flag;
#define sched_unsetScheduleFlag(flag)	sched_controlFlags &= ~flag

/*
 * Macros for testing flag status. Both for set and unset.
 */
#define testScheduleFlag(flag)		sched_controlFlags & flag
#define testScheduleFlag_n(flag)		(~sched_controlFlags & flag)

extern volatile int sched_controlFlags;


/*
 * Control flags.
 */
/* External Interrupt Flags */
#define HIGHEST_PRIORITY_FLAG			BIT0			/**< Flag to enable highest priority tasks */
#define PACKET_PENDING_FLAG				BIT1 			/**< Bit set when a received radio packet is waiting */
#define SYNCHRONISED_TASKS_FLAG			BIT4
/*
struct task {
	short counter;
    unsigned char priority;
	void (*execute)(struct task *t, void *data);
	void *data;
	struct task *next;
	struct task *prev;
};
*/
typedef enum {
	false = FALSE,
	true = TRUE
} boolean;

typedef enum {
	CLOCK_PERIODS = 0,
	SECONDS = 1
} TIMER_PERIOD;

typedef struct TASK_t {
	void (*execute)(void);
	int ctrl;
	volatile struct TASK_t* nextTask;
} TASK;

/**
 * Struct for scheduling tasks.
 *
 * Pointer nextTask is used to form lists in scheduler.
 *
 */
typedef struct SCHEDULED_TASK_t {
	TASK task;
	int period;
	int remaining;
	TIMER_PERIOD basePeriod;
	volatile struct SCHEDULED_TASK_t* nextTask;
} SCHEDULED_TASK;


extern volatile int sched_controlFlags;

extern boolean secDelayTimerActive;

extern boolean secDelayTimerActive;

extern volatile int currentTime;

extern volatile int nextSecInterrupt;

extern volatile int nextmsInterrupt;



void sched_init(void);

void sched_mainLoop(void);

void sched_addLowPriorityTask(TASK volatile *task);

void sched_addHighPriorityTask(TASK volatile *task);

void sched_addSynchronisedTask(TASK volatile *task);

void sched_addTimedTask(SCHEDULED_TASK* volatile task);

void sched_removeTimedTask(SCHEDULED_TASK* volatile task);

void sched_taskTimerISR(unsigned char timer);

/*
void add_task(struct scheduler *sched, struct task *t);

void remove_task(struct scheduler *sched, struct task *t);

void unlink_task(struct scheduler *sched, struct task *t);

void promote_task(struct scheduler *sched, struct task *t);

void print_task(struct task *t);

struct task * alloc_task (short freq, short delay, char repeat, void (*execute)(), void *data);

void tick(struct scheduler *sched);

void dispatch(struct scheduler *sched);
*/
